package questiontwo.usecase.impl;

import questiontwo.usecase.base.BaseChessPlayer;
import questiontwo.usecase.base.BaseObserver;
import questiontwo.usecase.base.BaseScene;
import questiontwo.usecase.common.Common;

/**
 * 裁判类
 */
public class Observer extends BaseObserver {
    //裁判类单例模式静态对象
    private static Observer observer = new Observer();
    //私有构造方法，实现单例模式
    private Observer() {
    }
    //获取唯一的裁判对象
    public static Observer GetInstance() {
        return observer;
    }

    /**
     * 检查落子是否有效，无效提示棋手重新落子
     * @param point 落子的坐标点（X,Y）
     * @return 返回是否有效
     */
    @Override
    public boolean CheckDropOff(String point) {
        if (point.indexOf(",") > 0) {
            String[] pointXY = point.split(",");
            Integer x = Common.TryParse(pointXY[0]);
            if (x == null) {
                System.out.println("棋手落子无效，请重新落子");
                return false;
            }
            Integer y = Common.TryParse(pointXY[1]);
            if (y == null) {
                System.out.println("棋手落子无效，请重新落子");
                return false;
            }
            if (BaseScene.Piece[x - 1][y - 1] != "+") {
                System.out.println("棋手落子无效，请重新落子");
                return false;
            }
        } else {
            System.out.println("棋手落子无效，请重新落子");
            return false;
        }
        return true;
    }

    /**
     * 更新棋盘棋子摆布情况，重新绘制棋盘
     * @param point 落子的坐标点（X,Y）
     * @param Piece 棋手的棋子
     */
    @Override
    public void UpdatePiece(String point, String Piece) {
        String[] pointXY = point.split(",");
        Integer x = Common.TryParse(pointXY[0]);
        Integer y = Common.TryParse(pointXY[1]);
        BaseScene.Piece[x - 1][y - 1] = Piece;
        scene.DrawCheckerBoard();
    }

    /**
     * 计算此次落子是否产生胜利者
     * @param point 落子的坐标点（X,Y）
     * @param Piece 棋手的棋子
     * @return
     */
    @Override
    public boolean IsVictory(String point, String Piece) {
        String[] pointXY = point.split(",");
        Integer x = Common.TryParse(pointXY[0]) - 1;
        Integer y = Common.TryParse(pointXY[1]) - 1;

        int xFrom = x - 4;
        int xTo = x + 4;
        int yFrom = y - 4;
        int yTo = y + 4;
        if (x - 4 < 0) {
            xFrom = 0;
        }
        if (x + 4 > BaseScene.Piece.length - 1) {
            xTo = BaseScene.Piece.length - 1;
        }
        if (y - 4 < 0) {
            yFrom = 0;
        }
        if (y + 4 > BaseScene.Piece[0].length - 1) {
            yTo = BaseScene.Piece[0].length - 1;
        }

        int horizontal = 0;
        int vertical = 0;
        int leftOblique = 0;
        int rightOblique = 0;
        for (int i = 0; i < 9; i++) {
            //判断水平是否满足胜利
            if (yFrom + i < BaseScene.Piece[0].length - 1) {
                if (BaseScene.Piece[x][yFrom + i].equals(Piece)) {
                    horizontal += 1;
                } else {
                    horizontal = 0;
                }
            }
            if (horizontal == 5) {
                return true;
            }
            //先判断垂直是否满足胜利
            if (xFrom + i < BaseScene.Piece.length - 1) {
                if (BaseScene.Piece[xFrom + i][y].equals(Piece)) {
                    vertical += 1;
                } else {
                    vertical = 0;
                }
            }
            if (vertical == 5) {
                return true;
            }
            //判断左斜是否满足胜利
            if (xTo + i < BaseScene.Piece.length - 1 && yFrom + i < BaseScene.Piece[0].length - 1) {
                if (BaseScene.Piece[xFrom + i][yFrom + i].equals(Piece)) {
                    leftOblique += 1;
                } else {
                    leftOblique = 0;
                }
            }
            if (leftOblique == 5) {
                return true;
            }
            //判断右斜是否满足胜利
            if (xFrom + i < BaseScene.Piece.length - 1 && yTo - i > 0) {
                if (BaseScene.Piece[xFrom + i][yTo - i].equals(Piece)) {
                    rightOblique += 1;
                } else {
                    rightOblique = 0;
                }
            }
            if (rightOblique == 5) {
                return true;
            }
        }
        return false;
    }

    /**
     * 游戏开始类
     * @param player1 玩家1
     * @param player2 玩家2
     */
    @Override
    public void Start(BaseChessPlayer player1, BaseChessPlayer player2) {
        System.out.println("游戏开始");
        this.set_playStatus(1);
        System.out.println(player1.getPlayerName() + "先手");
        for (int i = 0; i < BaseScene.Piece.length * BaseScene.Piece[0].length; i++) {
            if (this.get_playStatus() == 0) {
                break;
            }
            if (i % 2 == 0) {
                System.out.println("请" + player1.getPlayerName() + "落子,落子规则输入：数字（X坐标）,数字（Y坐标）");
                player1.PlayChess();
            } else {
                System.out.println("请" + player2.getPlayerName() + "落子,落子规则输入：数字（X坐标）,数字（Y坐标）");
                player2.PlayChess();
            }
        }
        if (this.get_playStatus() == 1) {
            System.out.println("平局");
            Stop();
        }
    }

    /**
     * 游戏结束类
     */
    @Override
    public void Stop() {
        this.set_playStatus(0);
        System.out.println("比赛结束");
    }
}
